package person.twj.accountservice.feign.client;

import com.alibaba.fastjson2.JSON;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import io.seata.core.context.RootContext;
import io.seata.rm.tcc.api.BusinessActionContext;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import person.twj.accountservice.entity.AccountFreezeTbl;
import person.twj.accountservice.entity.AccountTbl;
import person.twj.accountservice.service.IAccountFreezeTblService;
import person.twj.accountservice.service.IAccountTblService;

@Service

@Slf4j
public class TccAccountServiceImpl implements TccAccountService{

    private static final String SUCCESS = "SUCCESS";
    private static final String FAIL = "FAIL";

    @Autowired
    @Qualifier("accountTblServiceImpl")
    private IAccountTblService iAccountTblService;
    @Autowired
    @Qualifier("accountFreezeTblServiceImpl")
    private IAccountFreezeTblService iAccountFreezeTblService;

    @Override
    @Transactional
    public String account(String userId,
                          int money,
                          int type) {

        log.info("Account Service ... xid: " + RootContext.getXID());

        /*if (random.nextBoolean()) {
            throw new RuntimeException("this is a mock Exception");
        }*/
        AccountTbl account = iAccountTblService.getById(userId);
        log.info("原始ACCOUNT:"+ JSON.toJSONString(account));


        // 悬挂：查询是否已经处理过冻结金额了，这是怕重复冻结
//        AccountFreezeTbl accountFreeze = iAccountFreezeTblService.getById(RootContext.getXID());
//        if(accountFreeze!=null){
//            // 重复操作
//            return SUCCESS;
//        }



        UpdateWrapper wrapper = new UpdateWrapper();
        wrapper.setSql(true, " money = money - {0} where user_id = {1}",
                new Object[] { money, userId });

        boolean result = iAccountTblService.update(wrapper);

        if(type==1){
            throw new RuntimeException("type=1");
        }
        if (result) {
            boolean status = iAccountFreezeTblService.save(AccountFreezeTbl.builder()
                            .xid(RootContext.getXID())
                            .userId(userId)
                            .freezeMoney(money)
                            .status(AccountFreezeTbl.Status.TRY)
                    .build());
            if(status){
                log.info("执行try成功");
                return SUCCESS;
            }
            return FAIL;

        }
        return FAIL;

    }
    @Override
    public boolean commit(BusinessActionContext actionContext) {
        log.info("执行commit成功");
        // 冻结记录已经用完了，没必要存在了，所以删除冻结记录
        return iAccountFreezeTblService.removeById(actionContext.getXid());
    }
    @Override
    public boolean rollback(BusinessActionContext actionContext) {
        String userId = actionContext.getActionContext("userId").toString();
        AccountFreezeTbl freeze = iAccountFreezeTblService.getById(actionContext.getXid());
        //空回滚判断
//        if(freeze==null){
//            //证明try没执行，需要空回滚
//            freeze = AccountFreezeTbl.builder()
//                    .xid(actionContext.getXid())
//                    .userId(actionContext.getActionContext("userId").toString())
//                    .freezeMoney(0)
//                    .status(AccountFreezeTbl.Status.CANSEL)
//                    .build();
//            iAccountFreezeTblService.save(freeze);
//            return true;
//
//        }
//        // 幂等判断
//        if (freeze.getStatus() == AccountFreezeTbl.Status.CANSEL){
//            // 已经处理过一次了，不需要在重复处理了
//            return true;
//        }
        // 恢复可用金额
        UpdateWrapper wrapper = new UpdateWrapper();
        wrapper.setSql(true, " money = money + {0} where user_id = {1}",
                new Object[] { freeze.getFreezeMoney(), userId });

        boolean result = iAccountTblService.update(wrapper);

        if(result){
            freeze.setFreezeMoney(0);
            freeze.setStatus(AccountFreezeTbl.Status.CANSEL);
            boolean status = iAccountFreezeTblService.updateById(freeze);
            if(status){
                log.info("执行rollback成功");
                return true;
            }
        }

        return false;
    }
}
